package top.jnaw.jee.platform.sample;

import com.alibaba.fastjson.JSONArray;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import java.util.List;
import top.jnaw.jee.platform.Consts.Result;
import top.jnaw.jee.utils.ModelResult;
import top.jnaw.jee.utils.Models;
import top.jnaw.jee.utils.Strings;

public class ModelX {

  private Class clz;
  private String table;

  private ModelX() {
  }

  public ModelX(Class clz, String table) {
    this.clz = clz;
    this.table = table;
  }

//  public ModelResult add() {
//    ModelResult result = new ModelResult();
//    boolean save = false;
//
//    // [Neo] .TODO save
//
//    result.setObject(save ? m : null);
//    result.setResult(save ? Result.kSuccess : Result.kModelSaveError);
//    return result;
//  }

//  public ModelResult update(int id) {
//    ModelResult result = new ModelResult(Result.kObject);
//    boolean update = false;
//
//    // [Neo] .TODO findById(id);
//
//    // [Neo] .TODO update
//
//    result.setObject(update ? m : null);
//    result.setResult(update ? Result.kSuccess : Result.kModelUpdateError);
//    return result;
//  }

  // [Neo] .TODO remove duplication codes
  public static Result save(Model model, ModelResult result) {
    try {
      if (model.save()) {
        result.setResult(Result.kSuccess);
        result.setObject(model);
      } else {
        result.setResult(Result.kModelSaveError);
      }
    } catch (Exception e) {
      e.printStackTrace();
      result.setResult(Result.kException);
    }

    return result.getResult();
  }

  public static Result update(Model model, ModelResult result) {
    try {
      if (model.update()) {
        result.setResult(Result.kSuccess);
        result.setObject(model);
      } else {
        result.setResult(Result.kModelSaveError);
      }
    } catch (Exception e) {
      e.printStackTrace();
      result.setResult(Result.kException);
    }

    return result.getResult();
  }

  public ModelResult query(int id) {
    ModelResult result = new ModelResult(Result.kNull);
    Model model = Models.getModelByClass(clz);

    if (null != model) {
      model = model.dao().findById(id);
    }

    result.setObject(model);
    result.setResult(null != model ? Result.kSuccess : Result.kNull);
    return result;
  }

  public ModelResult delete(int id) {
    Model model = Models.getModelByClass(clz);

    ModelResult result = new ModelResult(Result.kModelDeleteError);
    if (null != model && model.dao().deleteById(id)) {
      result.setResult(Result.kSuccess);
    }

    return result;
  }

  public ModelResult delete(Integer[] ids) {
    ModelResult result = new ModelResult(Result.kModelDeleteError);

    if (null != ids) {
      String clause = Strings.genInClause(ids);

      if (null != clause) {
        int count = Db.update("DELETE"
            + " FROM " + table
            + " WHERE id IN " + clause);

        if (ids.length == count) {
          result.setResult(Result.kSuccess);
        }
      }
    }

    return result;
  }

  public ModelResult delete(JSONArray ids) {
    ModelResult result = new ModelResult(Result.kModelDeleteError);

    if (null != ids) {
      String clause = Strings.genInClause(ids);

      if (null != clause) {
        int count = Db.update("DELETE"
            + " FROM " + table + ""
            + " WHERE id IN " + clause);

        if (ids.size() == count) {
          result.setResult(Result.kSuccess);
        }
      }
    }

    return result;
  }

  public ModelResult list(String exceptSelect) {
    ModelResult result = new ModelResult(Result.kNull);

    List list = Models.list(clz, table, exceptSelect);

    result.setObject(list);
    result.setResult(null != list ? Result.kSuccess : Result.kNull);
    return result;
  }

  public ModelResult page(int page, int size, String exceptSelect) {
    ModelResult result = new ModelResult(Result.kNull);

    Page pages = Models.page(clz, table, page, size, exceptSelect);

    result.setObject(pages);
    result.setResult(null != pages ? Result.kSuccess : Result.kNull);
    return result;
  }

  public ModelResult count() {
    return count(null);
  }

  public ModelResult count(String exceptSelect) {
    ModelResult result = new ModelResult(Result.kNull);

    final String sql = "SELECT count(*) AS count"
        + " FROM " + table + ((null != exceptSelect) ? " " + exceptSelect : "");
    Record r = Db.findFirst(sql);

    if (null != r) {
      result.setObject(r);
      result.setResult(Result.kSuccess);
    }

    return result;
  }


}
